package org.dbstar.scheduler.mail;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.net.URL;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;

import org.apache.commons.io.IOUtils;
import org.dbstar.scheduler.beans.CmdJobConf;
import org.dbstar.scheduler.beans.Job;
import org.dbstar.scheduler.beans.JobConf;
import org.dbstar.scheduler.control.JobConfController;
import org.dbstar.scheduler.control.JobController;
import org.dbstar.scheduler.control.JobStatusChangeListener;
import org.dbstar.scheduler.control.exception.DaoException;
import org.dbstar.scheduler.job.JobStatus;
import org.dbstar.scheduler.utils.JobUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;


/**
 * Job执行结果邮件通知
 * 
 * @author 代波
 * @since 1.0.0
 * @version 1.0.0
 * @date 2012-5-30
 */
public class JobMailNotifier implements JobStatusChangeListener {
	private static final Logger LOGGER = LoggerFactory.getLogger(JobMailNotifier.class);
	private static final String WEB_APP_ROOT_KEY = "job.scheduler.root";

	private final JobConfController jobConfController;
	private final JavaMailSender javaMailSender;
	private final String from;
	private final String serverPath;

	public JobMailNotifier(JobController jobController, JobConfController jobConfController,
			JavaMailSender javaMailSender, String from, String serverPath) {
		super();
		this.jobConfController = jobConfController;
		this.javaMailSender = javaMailSender;
		this.from = from;
		this.serverPath = serverPath;
		// 注册监听器
		jobController.registJobStatusChangeListener(this, null, null, JobStatus.kill, JobStatus.cancel,
				JobStatus.error, JobStatus.finish);
	}

	@Override
	public void onJobStatusChange(Job job, JobStatus oldStatus, JobStatus newStatus) {
		if (CmdJobConf.JOB_TYPE.equals(job.getType()) && JobUtils.isFinished(newStatus) && !job.isSucceed()) {
			try {
				javaMailSender.send(buildMessage(job, jobConfController.getJobConf(job.getJobConfIdentifier())));
				LOGGER.info("邮件发送：job=" + job.getIdentifier().getStringIdentifier() + ", status=" + newStatus);
			} catch (MessagingException e) {
				LOGGER.error("邮件构建失败：job=" + job.getIdentifier().getStringIdentifier() + ", status=" + newStatus, e);
			} catch (Throwable e) {
				LOGGER.error("邮件发送失败：job=" + job.getIdentifier().getStringIdentifier() + ", status=" + newStatus, e);
			}
		}
	}

	private MimeMessage buildMessage(Job job, JobConf conf) throws MessagingException {
		MimeMessage message = javaMailSender.createMimeMessage();
		MimeMessageHelper helper = new MimeMessageHelper(message, true, "utf-8");
		helper.setFrom(from);
		helper.setTo(job.getSubmitter());
		try {
			helper.setSubject(buildSubject(job));
			String body = buildBody(job);
			helper.setText(body, true);

			// add the image
			String webRoot = System.getProperty(WEB_APP_ROOT_KEY);
			if (body.indexOf("cid:img_ok") >= 0) {
				helper.addInline("img_ok", new FileSystemResource(new File(webRoot, "images/icons/ok.jpg")));
			}
			if (body.indexOf("cid:img_error") >= 0) {
				helper.addInline("img_error", new FileSystemResource(new File(webRoot, "images/icons/error.png")));
			}
			if (body.indexOf("cid:img_skip") >= 0) {
				helper.addInline("img_skip", new FileSystemResource(new File(webRoot, "images/icons/remove.jpg")));
			}
		} catch (MessagingException e) {
			throw e;
		} catch (Exception e) {
			throw new MessagingException("无法获取Job信息", e);
		}
		return message;
	}

	private String buildBody(Job job) throws IOException {
		URL url = new URL(serverPath + "/job-result.action?mail&identifier="
				+ job.getIdentifier().getStringIdentifier());
		InputStream in = url.openStream();
		StringWriter writer = new StringWriter();
		IOUtils.copy(in, writer, "utf-8");
		IOUtils.closeQuietly(in);
		IOUtils.closeQuietly(writer);
		return writer.toString();
	}

	private String buildSubject(Job job) throws DaoException {
		StringBuilder builder = new StringBuilder();
		builder.append("Job执行").append(job.isSucceed() ? "成功" : "失败").append(':');
		builder.append('[').append(job.getStatus().name()).append(']');
		JobConf conf = jobConfController.getJobConf(job.getJobConfIdentifier());
		builder.append(' ').append(conf.getName()).append(" - ").append(job.getIdentifier().getStringIdentifier());
		return builder.toString();
	}
}
